package com.dyh.quickdemozwei.deliver;

import java.util.*;
import java.util.function.Function;

public class OneManyReference  {
    Map<String, Set<String>> forwardMap = new HashMap<>();
    Map<String,String> reverseMap = new HashMap<>();

    public <T> void updateByAuto(Collection<T> datas, Function<T,String> tf, Function<T,String> tr){
        for (T data : datas) {
            forwardMap.computeIfAbsent(tf.apply(data),x->new HashSet<>())
                    .add(tr.apply(data));
            ;
            reverseMap.put(tr.apply(data),tf.apply(data));
        }
    }


    public  void updateByAuto(String f,String r){
        forwardMap.computeIfAbsent(f,x->new HashSet<>())
                .add(r);

        reverseMap.put(r,f);
    }



    public OneManyReference  infer(OneOneReference other){

        OneManyReference resultReference = new OneManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            for (String s : entry.getValue()) {
                String nv = other.getForward(s);
                if (nv!=null){
                    resultReference.updateByAuto(entry.getKey(),nv);
                }
            }

        }

        return resultReference;

    }


    public OneManyReference infer(OneManyReference other){
        OneManyReference resultReference = new OneManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            for (String s : entry.getValue()) {
                Set<String> nv = other.getForward(s);
                if (nv!=null){
                    nv.forEach(x->resultReference.updateByAuto(entry.getKey(),x));

                }
            }

        }
        return resultReference;
    }

    public ManyManyReference infer(ManyManyReference other){
        ManyManyReference resultReference = new ManyManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            for (String s : entry.getValue()) {
                Set<String> nv = other.getForward(s);
                if (nv!=null){
                    nv.forEach(x->resultReference.updateByAuto(entry.getKey(),x));

                }
            }

        }
        return resultReference;
    }


    public ManyManyReference inferx(OneManyReference other){
        ManyManyReference resultReference = new ManyManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            for (String s : entry.getValue()) {
                Set<String> nv = other.getForward(s);
                if (nv!=null){
                    nv.forEach(x->resultReference.updateByAuto(entry.getKey(),x));

                }
            }

        }

        return resultReference;
    }




    public Set<String> getForward(String k){
        return forwardMap.get(k);
    }

    public String getReverse(String k){
        return reverseMap.get(k);
    }

    public Map<String, Set<String>> getForwardMap() {
        return forwardMap;
    }

    public void setForwardMap(Map<String, Set<String>> forwardMap) {
        this.forwardMap = forwardMap;
    }

    public Map<String, String> getReverseMap() {
        return reverseMap;
    }

    public void setReverseMap(Map<String, String> reverseMap) {
        this.reverseMap = reverseMap;
    }
}